package ru.spbu.math.android.cbrf.dataprovider.handlers;

import java.util.ArrayList;
import java.util.List;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import ru.spbu.math.android.cbrf.model.Rate;
import ru.spbu.math.android.cbrf.model.StockItem;
import ru.spbu.math.android.cbrf.model.StockItemStore;

/**
 * @author  Helga
 */
public class YandexDynamicSaxHandler extends DefaultHandler {

	private final String X = "x";
	private final String Y = "y";

	private List<Rate> rateList;
	/**
	 * @uml.property  name="rate"
	 * @uml.associationEnd  
	 */
	private Rate rate;
	private StringBuilder builder;
	/**
	 * @uml.property  name="source"
	 * @uml.associationEnd  
	 */
	private StockItem source;
	/**
	 * @uml.property  name="target"
	 * @uml.associationEnd  
	 */
	private StockItem target;

	public void characters(char[] ch, int start, int length)
			throws SAXException {
		builder.append(ch, start, length);
	}

	public void startDocument() throws SAXException {
		rateList = new ArrayList<Rate>();
		builder = new StringBuilder();
	}

	public void startElement(String uri, String localName, String name,
			Attributes attributes) throws SAXException {
		ArrayList<String> timeList = new ArrayList<String>();
		ArrayList<Double> value = new ArrayList<Double>();
		if (localName.equalsIgnoreCase(X)) {
			while (localName.equalsIgnoreCase(X)) {
				timeList.add(builder.toString());
			}
		} else if (localName.equalsIgnoreCase(Y)) {
			while (localName.equalsIgnoreCase(Y)) {
				value.add(Double.valueOf(builder.toString()));
			}
		}
		for (int i = 0; i < timeList.size(); i++) {
			this.rate = new Rate();
			rate.setDate(timeList.get(i));
			rate.setSource(source);
			rate.setTarget(target);
			rate.setValue(value.get(i));
			StockItemStore itemStore = StockItemStore.Instance();
			StockItem stockItem = new StockItem();
			stockItem = itemStore.findByCode("USD");
			rate.setTarget(stockItem);
			rateList.add(rate);
		}
	}

	public List<Rate> getRateItem(long dateStart, long dateFinish) {
    	List<Rate> dynamicList = new ArrayList<Rate>();
    	int currPos = search(dateStart, dateFinish);
    	if(currPos == 0){
    		return null;
    	}
    	while(rateList.get(currPos).getDate().getTime() >= dateFinish){
    		dynamicList.add(rateList.get(currPos));
    		currPos ++;
    	}
        return dynamicList;
    }

	public List<Rate> getRateItem() {
		return rateList;
	}

	/**
	 * @param sourceItem
	 * @uml.property  name="source"
	 */
	public void setSource(StockItem sourceItem) {
		source = sourceItem;
	}

	/**
	 * @param targetItem
	 * @uml.property  name="target"
	 */
	public void setTarget(StockItem targetItem) {
		target = targetItem;
	}

	public int search(long timeStart, long timeFinish){
    	int start = 0;
    	int finish = rateList.size();
    	while(start < finish - 1){
    		int middle = (int)(finish - start)/2;
    		if(rateList.get(middle).getDate().getTime() >= timeStart) {
    			if (rateList.get(middle - 1).getDate().getTime() <= timeStart){
    				return middle;
    			} else {
    				finish = middle;
    			}
    		} else {
    			start = middle;
    		}
    	}
    	return 0;
    }
}
